﻿
using System.Linq.Expressions;
using System.Reflection;

namespace TotalApplication.Core 
{ 
    public static class ExpressionHelper
    {
        /// <summary>
        /// Compiles the expression and gets the function return values.
        /// </summary>
        /// <typeparam name="T">the type of return value</typeparam>
        /// <param name="lambda">the expression to compile</param>
        /// <returns></returns>
        public static T GetValue<T>(this Expression<Func<T>> lambda)
        {
            return lambda.Compile().Invoke();
        }

        public static void SetValue<T>(this Expression<Func<T>> lambda, T value)
        {

            if (lambda.Body is not MemberExpression expression)
                throw new ArgumentException("The body of the lambda expression must be a MemberExpression.", nameof(lambda));

            if (expression.Member is not PropertyInfo propertyInfo)
                throw new ArgumentException("The member accessed by the lambda expression must be a property.", nameof(lambda));

            if(expression.Expression is not Expression ex)
                throw new ArgumentException("The Expression of the lambda expression must be a Expression.", nameof(lambda));

            var target = Expression.Lambda(ex).Compile().DynamicInvoke();

            if (target == null)
                throw new InvalidOperationException("Unable to determine the target object for the property.");

            propertyInfo.SetValue(target, value);
        }
    }
}
